#!/usr/bin/python
# -*- coding: utf-8 -*-

# Copyright (C) 1994  Ling Li
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


import gobject, gtk, gtk.glade
from gtk import *
from UserDict import UserDict

import locale, gettext, re, string, os.path

from coralftp_globals import *

def get_glade_xml(name):
    return glade.XML(os.path.join(coralftp_datadir, 'coralftp.glade'), name)

def unicode_to_utf8(s):
    return s.encode('utf-8')

def utf8_to_unicode(s):
    if not isinstance(s, unicode):
        return unicode(s, 'utf-8')
    else:
        return s

def locale_to_utf8(s):
    cs = locale.nl_langinfo(locale.CODESET)
    if cs != 'UTF-8':
        try:
            return unicode(s, cs).encode('utf-8')
        except UnicodeDecodeError:
            return s
    else:
        return s

def locale_to_unicode(s):
    try:
        return unicode(s, locale.nl_langinfo(locale.CODESET))
    except UnicodeDecodeError:
        return s

def format_size(form, size):
    if form == '(1,)': form = 'KB'
    elif form == '(2,)': form = 'Bytes'
    else: form = 'Auto'
    if form == 'Auto':
        if size < 1024:
            form = 'Bytes'
        elif size >= 1024 and size < 1024 * 1024:
            form = 'KB'
        elif size >= 1024 * 1024 and size <= 1024 * 1024 * 1024:
            form = 'MB'
        else:
            form = 'GB'
    if form == 'Bytes':
        return str(size)
    elif form == 'KB':
        size = "%.2f" % (size / 1024.0)
    elif form == 'MB':
        size = "%.2f" % (size / (1024.0 * 1024.0))
    elif form == 'GB':
        size = "%.2f" % (size / (1024.0 * 1024.0 * 1024.0))
    size = string.rstrip(size, '0')
    size = string.rstrip(size, '.')
    return "%s %s" % (size, form)

def show_error_message(errmsg):
    dlg = MessageDialog(flags=DIALOG_MODAL,
                        type=MESSAGE_ERROR,
                        buttons=BUTTONS_OK,
                        message_format=errmsg)
    dlg.connect('response', lambda obj, *args: obj.destroy())
    dlg.show()
    dlg.set_modal(True)
    return

def ftpurl_parse(url):
    r = re.compile('ftp://((?P<username>[^:]*)(:(?P<password>.*))?@)?(?P<server>[a-zA-Z0-9\.\-\_]*)(:(?P<port>\d{1,5}))?(?P<path>/.*)?')
    m = r.match(url)
    if m == None:
        return None
    else:
        return (m.group('username'), m.group('password'),
                m.group('server'), m.group('port'), m.group('path'))

def get_month_index(month):
    if month == 'Jan': return 1
    elif month == 'Feb': return 2
    elif month == 'Mar': return 3
    elif month == 'Apr': return 4
    elif month == 'May': return 5
    elif month == 'Jun': return 6
    elif month == 'Jul': return 7
    elif month == 'Aug': return 8
    elif month == 'Sep': return 9
    elif month == 'Oct': return 10
    elif month == 'Nov': return 11
    elif month == 'Dec': return 12
    return 0

class ActionList(UserDict):

    def __init__(self, action_def):
        UserDict.__init__(self)
        self.__tooltips = gtk.Tooltips()
        for action_name, action_data in action_def.items():
            a = self.new_action(action_name)            
            for key, value in action_data.items():
                if key in ('update', 'execute'):
                    a.connect(key, value)
                elif key in ('label', 'tooltip', 'sensitive', 'visible'):
                    a.set_property(key, value)
        return

    def __getattr__(self, name):
        if name == 'tooltips':
            return self.__tooltips
        else:
            raise AttributeError, name

    def new_action(self, action_name):
        self.data[action_name] = Action(self)
        return self.data[action_name]

class Action(gobject.GObject):

    DEFAULT_TIMEOUT = 300

    __gproperties__ = {
        'label': (gobject.TYPE_STRING, 'label property',
                  'the label of the button or menu item',
                  '', gobject.PARAM_READWRITE),
        'tooltip': (gobject.TYPE_STRING, 'tooltip property',
                  'the tooltip of the button or menu item',
                  '', gobject.PARAM_READWRITE),
        'sensitive' : (gobject.TYPE_BOOLEAN, 'sensitity property',
                       'is the button or menu item sensitive',
                       True, gobject.PARAM_READWRITE),
        'visible' : (gobject.TYPE_BOOLEAN, 'visible property',
                     'is the button or menu item visible',
                     True, gobject.PARAM_READWRITE)
    }

    __gsignals__ = {
        'update'  : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ()),
        'execute' : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
                     (gobject.TYPE_PYOBJECT,)),
        }

    __label = None
    __tooltip = ''
    __sensitive = True
    __visible = True

    def __init__(self, owner):
        self.__gobject_init__()
        self.__owner = owner
        self.__widgets = []

    def __del__(self):
        self.remove()
        
    def remove(self):
        gobject.source_remove(self.__tid)

    def __call__(self):
        self.__tid = gobject.timeout_add(self.DEFAULT_TIMEOUT, self.update)
        return False

    def attach(self, widget):
        def on_widget_clicked(obj, *args):
            self.emit('execute', obj)
            return
        
        if len(self.__widgets) == 0:
            gobject.idle_add(self)
        if widget == None:
            raise ValueError
        self.__widgets.append(widget)
        if isinstance(widget, gtk.ToolButton):
            widget.connect('clicked', on_widget_clicked)
            if self.__label:
                widget.set_label(string.replace(self.__label, '_', ''))
            widget.set_sensitive(self.__sensitive)
            widget.set_property('visible', self.__visible)
        elif isinstance(widget, gtk.Button):
            widget.connect('clicked', on_widget_clicked)
            if self.__label:
                if isinstance(widget, gtk.Button):
                    widget.set_label(string.replace(self.__label, '_', ''))
                else:
                    widget.set_label(self.__label)
            widget.set_sensitive(self.__sensitive)
            widget.set_property('visible', self.__visible)
            self.__owner.tooltips.set_tip(widget, self.__tooltip)
        elif isinstance(widget, gtk.MenuItem):
            widget.connect('activate', on_widget_clicked)
            widget.set_property('sensitive', self.__sensitive)
            widget.set_property('visible', self.__visible)
        return
            
        
    def update(self):
        self.emit("update")
        return True
 
    def do_set_property(self, pspec, value):
        if pspec.name == 'label':
            if value and self.__label != value:
                self.__label = value
                for widget in self.__widgets:
                    if isinstance(widget, gtk.Button):
                        widget.set_label(string.replace(value, '_', ''))
                    else:
                        widget.set_label(value)
        elif pspec.name == 'tooltip':
            if self.__tooltip != value:
                self.__tooltip = value
                for widget in self.__widgets:
                    if type(widget) == gtk.Button:
                        self.__owner.tooltips.set_tip(widget, value)
        elif pspec.name == 'sensitive':
            if self.__sensitive != value:
                self.__sensitive = value
                for widget in self.__widgets:
                    widget.set_property('sensitive', value)
        elif pspec.name == 'visible':
            if self.__visible != value:
                self.__visible = value
                for widget in self.__widgets:
                    widget.set_property('visible', value)
        else:
            raise AttributeError, 'unknown property %s' % pspec.name

    def do_get_property(self, pspec):
        if pspec.name == 'label':
            return self.__label
        elif pspec.name == 'tooltip':
            return self.__tooltip
        elif pspec.name == 'sensitive':
            return self.__sensitive
        elif pspec.name == 'visible':
            return self.__visible
        else:
            raise AttributeError, 'unknown property %s' % pspec.name
    
gobject.type_register(Action)
